import math
import time
import os
# import uuid
import cv2
from PIL import Image
import numpy as np

import torch
from PIL import Image
# from yolov8_BW.yolov8_BW import YOLOV8
# from yolov8_4.yolov8_4 import YOLOV8
from yolov8_5.yolov8_5 import YOLOV8


os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"



class DigitalProcessor_5():
    def __init__(self, model=0):
        self.model = model
        self.yolo_predicter = YOLOV8(model_type='s')



    def call(self, img_path):
        # 读取图片
       
        # img = Image.open(img_path)
       
        # print(f"读取图片时间：{end_1time - start_1time}秒")
        #需要对图片进行预处理，letterbox

        # image_filename = os.path.basename(img_path)
        # # original_image_path = os.path.join(output_folder, image_filename)
        # original_image = cv2.imread(img_path)

        # # 获取原始图像的尺寸
        # original_height, original_width, _ = original_image.shape

        # # 计算Letterbox调整后的图像大小
        # scale = min(640 / original_width, 640 / original_height)
        # new_width = int(original_width * scale)
        # new_height = int(original_height * scale)

        # # 使用OpenCV的resize函数进行Letterbox调整
        # letterboxed_image = cv2.resize(original_image, (new_width, new_height))

        # # 在目标大小的画布上创建灰色背景
        # canvas = np.full((640, 640, 3), 128, dtype=np.uint8)

        # # 计算图像在画布上的位置
        # x_offset = (640 - new_width) // 2
        # y_offset = (640 - new_height) // 2

        # # 将Letterbox调整后的图像放置到画布上
        # canvas[y_offset:y_offset + new_height, x_offset:x_offset + new_width] = letterboxed_image

        # # 保存Letterbox调整后的图像
        # cv2.imwrite(img_path, canvas)
        # img = Image.open(img_path)

        
        xyxyn,cls = self.yolo_predicter.predict(img_path)

        # 后处理
                # 计算每个框的宽度
        widths = xyxyn[:, 2] - xyxyn[:, 0]

        # 计算每个框的高度
        heights = xyxyn[:, 3] - xyxyn[:, 1]
        areas = widths * heights
        print('areas',areas)
        # 计算平均面积
        mean_area = areas.mean()

        # 找到小于平均面积60%的框的索引
        mask = areas < 0.6 * mean_area

        # 删除面积小于平均面积50%的框和对应的类别
        xyxyn = xyxyn[~mask]
        cls = cls[~mask]
       
        # print(f"YOLOX检测时间：{end_2time - start_2time}秒")
        #对返回来的进行判断，若出现下标是模糊的直接报错，先进行从左到右排序，
        # 根据第一个张量的第一列进行排序，并调整第二个张量的位置关系
        sorted_values, sorted_indices = torch.sort(xyxyn[:, 0])
        cls = cls[sorted_indices]
        # print('sorted_tensor2',sorted_tensor2)
        # 检查元素是否存在
        element_to_find = 20
        contains_element = torch.any(cls == element_to_find).item()

        if contains_element:
            #存在模糊字符，报错
            return 'error'
        else:
            #将下标替换成对应的真是数字
            
            # 定义变化规则
            conversion_rules = {
                0:0, 1:0.5, 2:1, 3:1.5, 4:2, 5:2.5,
                6:3, 7:3.5, 8:4, 9:4.5, 10:5,
                11:5.5, 12:6, 13:6.5, 14:7, 15:7.5,
                16:8, 17:8.5, 18:9, 19:9.5, 20:20
            }

            # 更新原始张量
            for i in range(len(cls)):
                original_value = cls[i].item()
                new_value = conversion_rules.get(original_value, original_value)
                cls[i] = new_value

            print("Updated tensor:", cls)
            # formatted_numbers = []

            # # 遍历张量中的每个数字
            # for i, num in enumerate(sorted_tensor2):
            #     # 如果数字是小数并且在数组的最后，则保留小数部分并转换为字符串
            #     if num.item() != int(num) and i == len(sorted_tensor2) - 1:
            #         formatted_numbers.append(str(round(num.item(), 3)))
            #     # 否则，向下取整并转换为字符串
            #     else:
            #         formatted_numbers.append(str(int(num)))
            # if len(formatted_numbers)<3:return 'error'

            # # 将处理后的数字拼接成字符串
            # result = ''.join(formatted_numbers)
            # return result
            # #将不是最后一位数字的先进行向下取整再拼接
            results = ''.join(str(math.floor(x.item())) for x in cls) # 沿着默认的维度0进行连接
            # print(concatenated_string)
            if len(results)<3:return 'error'
            return results


 

           



if __name__ == "__main__":
    start1_time = time.time()
    digital = DigitalProcessor_4()
    end1_time = time.time()
    # 计算时间差
    elapsed_time = end1_time - start1_time
    # 打印时间差
   
    num=digital.call(r'D:\HisCameraImage\911070002006\911070002006_20230706.jpg')
    print('num的结果是',num)


    # # 遍历文件夹下所有文件
    # dir_path = r"/home/chuanzhi/zy/watermeter/1W"
    # files = os.listdir(dir_path)

    # # 过滤出所有图片文件
    # #img_files = [file for file in files if file.endswith(('jpg', 'jpeg', 'png', 'bmp', 'gif')) ]

    # # 读取每个图片文件并将文件名、图像和顺序编号保存到一个列表中
    # data = []
    # time_sum=0
    # img_num=0
    # for i, file in enumerate(files):
    #     start2_time = time.time()
    #     img_path = os.path.join(dir_path, file)
    #     img = Image1(img_path)
    #     data.append((digital.call(img_path), file, img))
    #     print(i)
    #     if i > 10001:
    #         break
    #     # if (i+1) % 3 == 0:
    #     #     break
    #     # 记录结束时间
    #     end2_time = time.time()
    #     # 计算时间差
    #     elapsed_time = end2_time - start2_time
    #     print(f"代码执行时间：{elapsed_time}秒")

    #     time_sum = time_sum+elapsed_time
    #     img_num=img_num+1

    #     print("time_sum"+str(time_sum))
    #     print("average: "+str(time_sum/img_num))





